package com.golang.api.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;


public class ObjectUtils {

    public static final DecimalFormat df = new DecimalFormat();
    public static final DecimalFormat TwoDigitalFormat = new DecimalFormat("0.00##");
    public static final DecimalFormat ignoreZeroDigitalFormat = new DecimalFormat("#.##");
    public static final DecimalFormat ignoreZero3DigitalFormat = new DecimalFormat("#.###");
    public static final DecimalFormat percentFormat = new DecimalFormat("#.##%");
    public static final DecimalFormat signedFormat = new DecimalFormat("+ 0.00;- 0.00");
    public static final DecimalFormat signedIntFormat = new DecimalFormat("+ 0;- 0");
    public static final BigDecimal wan = BigDecimal.valueOf(10000);

    public static Long obj2Long(Object obj, Long defaultValue){
        if(obj == null) {
            return defaultValue;
        }
        try {
            return Long.parseLong(obj.toString());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    public static Integer obj2Integer(Object obj, Integer defaultValue){
        if(obj == null) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(obj.toString());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    public static Double obj2Double(Object obj, Double defaultValue){
        if(obj == null) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(obj.toString());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    public static boolean obj2Boolean(Object obj, boolean defaultValue){
        if(obj == null) {
            return defaultValue;
        }
        return obj.toString().equals("true") || obj.toString().equals("1");
    }

    public static BigDecimal obj2BigDecimal(Object obj){
        return obj2BigDecimal(obj, null);
    }

    public static BigDecimal obj2BigDecimal(Object obj, BigDecimal defaultValue){
        if(obj == null) {
            return defaultValue;
        }
        try {
            return new BigDecimal(obj.toString());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    public static BigDecimal obj2BigDecimal(Object obj, int scale, RoundingMode mode){
        return obj2BigDecimal(obj, null, scale, mode);
    }

    public static BigDecimal obj2BigDecimal(Object obj, BigDecimal defaultValue, int scale, RoundingMode mode){
        if(obj == null) {
            return defaultValue;
        }
        try {
            return new BigDecimal(obj.toString()).setScale(scale, mode);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    public static String format(BigDecimal num, String pattern){
        if(num == null) {
            num = BigDecimal.ZERO;
        }
        df.applyPattern(pattern);
        return df.format(num);
    }

    public static String formatTwoDigital(BigDecimal num){
        if(num == null) {
            return "0.00";
        }
        return TwoDigitalFormat.format(num);
    }

    public static String formatIgnorZeroDigital (BigDecimal num){
        if(num == null) {
            return "0";
        }
        return ignoreZeroDigitalFormat.format(num);
    }

    public static String format3DigitalIgnoreZero (BigDecimal num){
        if(num == null) {
            return "0";
        }
        return ignoreZero3DigitalFormat.format(num);
    }

    public static String formatPercent(BigDecimal num){
        if(num == null) {
            return "0%";
        }
        return percentFormat.format(num);
    }

    public static String formatSigned(BigDecimal num){
        if(num == null) {
            return "0.00";
        }
        return signedFormat.format(num);
    }

    public static String formatWan(BigDecimal num){
        if(num == null) {
            return "0";
        }
        if(num.compareTo(wan) >= 0){
            return formatIgnorZeroDigital(num.divide(wan, BigDecimal.ROUND_DOWN)) + "万";
        }
        return formatIgnorZeroDigital(num) + "元";
    }

    public static String formatSigned(Integer num){
        if (num == null) {
            return "0";
        }
        return signedIntFormat.format(num);
    }

    public static String calcRatio(BigDecimal cur, BigDecimal last){
        return calcRatio(cur == null ? 0 : cur.doubleValue(), last == null ? 0 : last.doubleValue());
    }

    public static String calcRatio(Integer cur, Integer last){
        return calcRatio(cur == null ? 0 : cur.doubleValue(), last == null ? 0 : last.doubleValue());
    }

    public static String calcRatio(Double cur, Double last){
        cur = ObjectUtils.ifNull(cur, 0.0);
        last = ObjectUtils.ifNull(last, 0.0);
        if(last == 0 && cur == 0) {
            return "0";
        }else if(last == 0){
            return "";
        }else {
            return ignoreZeroDigitalFormat.format((cur - last) / last);
        }
    }

    public static String calcTimePast(long time){
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
        long minutes = dateTime.until(LocalDateTime.now(), ChronoUnit.MINUTES);
        if(minutes == 0){
            return "刚刚";
        }else if(minutes < 60){
            return minutes + "分钟前";
        }else if(minutes < 24 * 60){
            return minutes / 60 + "小时前";
        }else {
            return minutes / 60 / 24 + "天前";
        }
    }

    public static <T> T ifNull(T value, T defaultValue){
        return value == null ? defaultValue : value;
    }

    public static <T> T firstNonNull(T... values) {
        if (values != null) {
            for(int i = 0; i < values.length; ++i) {
                T val = values[i];
                if (val != null) {
                    return val;
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {

    }
}
